package com.security.control.web.controller;

import com.fasterxml.jackson.annotation.JsonView;
import com.security.control.core.properties.OAuth2Properties;
import com.security.control.entity.User;
import com.security.control.web.dto.UserQueryCondition;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.security.core.Authentication;
import org.springframework.social.connect.web.ProviderSignInUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.ServletWebRequest;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;

/**
 * @author imoot@gamil.com
 * @date 2018/12/14 0014 14:05
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private ProviderSignInUtils providerSignInUtils;

    @Autowired
    private OAuth2Properties oAuth2Properties;

    /*@Autowired
    private AppSignUpUtils appSignUpUtils;*/

    private Logger log = LoggerFactory.getLogger(UserController.class);

    @GetMapping("/me")
    public Object getCurrentUser(Authentication authentication, HttpServletRequest request) throws Exception {
        /*String header = request.getHeader("Authorization");
        String token = StringUtils.substringAfter(header, "bearer ");
        Claims claims = Jwts.parser().setSigningKey(oAuth2Properties.getSigningKey().getBytes("UTF-8")).parseClaimsJws(token).getBody();
        String org = claims.get("org").toString();
        log.info("org---------->" + org);*/
        return authentication.getPrincipal();
    }

    /*--参数：@RequestParam(required = false,defaultValue = "test") String userId
     *--Pageable：（注意包 org.springframework.data.domain.Pageable）
     *   size----->每页多少条数据
     *   page---->当前页
     *   sort------>按照xxx字段排asc/desc序
     *--@JsonView(User.UserSimpleView.class)限制了用户的某些属性在这个api下不展示
     */
    //@RequestMapping(method = RequestMethod.GET)
    @GetMapping
    //@ResponseBody
    @JsonView(User.UserSimpleView.class)
    @ApiOperation(value = "查询用户列表", notes = "查询用户列表")
    @ApiImplicitParam(name = "userList", value = "用户列表", required = true, dataType = "Object")
    public Object getUser(UserQueryCondition condition, @PageableDefault(page = 1, size = 10, sort = "userId") Pageable page) {
       /* if(StringUtils.isEmpty(condition.getUserId())){
            throw new UserNotExistException(condition.getUserId());
        }*/
        System.out.println("getUser");
        System.out.println(condition.getUserId());
        System.out.println(page.getPageSize());
        System.out.println(page.getPageNumber());
        System.out.println(page.getSort());
        List<User> userList = new ArrayList<>();
        User user = new User();
        user.setId("test");
        user.setUsername("test");
        user.setPassword("000");
        userList.add(user);
        userList.add(user);
        userList.add(user);
        userList.add(user);
        return userList;
    }

    /*
     * --@PathVariable把请求url中用通配符形式的参数名映射到方法的参数上
     *         name属性会让方法参数匹配到与name值相同的表达式上
     * --请求url的表达式中可以加入正则表达式来限制参数格式（例如："/user/{id:\\d+}"）
     * --@JsonView(User.UserDetailView.class)限制了用户的某些属性在这个api下展示
     */
    //@RequestMapping(value = "/{id:\\d+}", method = RequestMethod.GET)
    @GetMapping("/{id:\\d+}")
    @JsonView(User.UserDetailView.class)
    @ApiOperation(value = "查询用户", notes = "查询用户")
    @ApiImplicitParam(name = "user", value = "用户", required = true, dataType = "User")
    public User getInfo(@ApiParam(value = "用户id") @PathVariable(name = "id") String userId) {
        //throw new UserNotExistException(userId);//如果抛出已声明要处理的异常类，自定义Interceptor不执行postHandle()，但是afterCompletion()拿不到异常信息
        //throw new RuntimeException("user not exist");//如果抛出未声明要处理的异常类，自定义Interceptor不执行postHandle()，但是afterCompletion()可以拿到异常信息
        User user = new User();
        user.setId(userId);
        user.setUsername("test");
        user.setPassword("000");
        return user;
    }

    /*
       --@RequestBody把请求的json参数映射到实体
       --@NotBlank需要搭配@Valid使用，才会对属性进行非空校验（其它校验类似）
       --BindingResult会在校验错误时不强制退出方法，而是把错误保存后进入方法内
    */
    @PostMapping
    public User create(@Valid @RequestBody User user/*, BindingResult errors*/) {
       /* if (errors.hasErrors()) {
            errors.getAllErrors().stream().forEach(error -> System.out.println(error.getDefaultMessage()));
        }*/
        user.setId("123");
        System.out.println(user.toString());
        return user;
    }

    @PostMapping("/register")
    public void register(User user, HttpServletRequest request) {
        //不论是注册还是绑定用户，都会有一个唯一标识
        String userName = user.getUsername();
        //providerSignInUtils.doPostSignUp(userName, new ServletWebRequest(request));//把用户唯一标识与request传递给SpringSocial，并插入数据库（基于session）
        //appSignUpUtils.doPostSignUp(new ServletWebRequest(request), userName);
    }

    @PutMapping("/{id:\\d+}")
    public User update(@Valid @RequestBody User user, BindingResult errors) {
        if (errors.hasErrors()) {
            errors.getAllErrors().stream().forEach(error -> {
                FieldError fieldError = (FieldError) error;
                System.out.println(fieldError.getField() + "     " + error.getDefaultMessage());
            });
        }
        System.out.println(user.toString());
        return user;
    }

    @DeleteMapping("/{id:\\d+}")
    public void delete(@PathVariable String id) {
        System.out.println(id);
    }
}
